package com.citywithincity.utils;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.citywithincity.api.ApiConfig;
import com.citywithincity.models.Models;


public class CachedClassUtil {
	
	private static Map<Class<?>, Field[]> map = new ConcurrentHashMap<Class<?>, Field[]>();
	
	
	/**
	 * 获取public field
	 * 
	 * @param clazz
	 * @return
	 */
	/**
	 * 线程安全的
	 * @param clazz
	 * @return
	 */
	public static Field[] getFields(Class<?> clazz) {
		Field[] fields = map.get(clazz);
		if(fields==null){
			synchronized (map) {
				fields = map.get(clazz);
				if(fields==null){
					fields = ClassUtil.getFields(clazz);
					for (Field field : fields) {
						field.setAccessible(true);
					}
					map.put(clazz, fields);
				}
			}
		}
		return fields;
	}
	
	private static HashMap<Class<?>, Object> cachedValues = new HashMap<Class<?>, Object>();
	
	/**
	 * 非线程安全注意
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T newInstance(Class<?> clazz){
		Object value = cachedValues.get(clazz);
		if(value==null){
			try {
				value = clazz.newInstance();
			} catch (Exception e) {
				ApiConfig.error(e);
				throw new RuntimeException(e);
			} 
			cachedValues.put(clazz, value);
		}
		return (T) value;
	}
	
	
	public static <T> T newController(Class<?> controllerClass){
		Object value = cachedValues.get(controllerClass);
		if(value==null){
			try {
				value = controllerClass.newInstance();
				Models.assignModels(value);
			} catch (Exception e) {
				ApiConfig.error(e);
				throw new RuntimeException("Create controller "+controllerClass+" fail",e);
			} 
			cachedValues.put(controllerClass, value);
		}
		return (T) value;
		
	}
	
}
